package org.example.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Component
@Aspect  //设置当前类为AOP切面类
public class MyAdvice {

    @Pointcut("execution(void org.org.example.dao.BookDao.update())")
    private void pt(){}

    @Pointcut("execution(int org.org.example.dao.BookDao.save())")
    private void ptx(){};

    /***
     *  @Around("pt()")
     *  public void method(ProceedingJoinPoint pjp) throws Throwable{
     *      System.out.println("around before advice ...");
     *      pjp.proceed();
     *      System.out.println("around after advice ...");
     *   }
     * 但是原始方法的内容却没有被执行。
     * 因为环绕通知需要在原始方法的前后进行增强，所以环绕通知就必须要能对原始操作进行调用
     */

    @After("pt()")
    public void method2(){
        System.out.println("around after advice ...");
    }

//    @Around("ptx()")
//    public Object method3(ProceedingJoinPoint pjp) throws Throwable{
//        System.out.println("around before advice ...");
//        Object  ret= pjp.proceed(); //表示对原始操作的调用
//        System.out.println("around after advice ...");
//        return  ret;
//    }

    /***
     * 返回后通知是需要在原始方法select正常执行后才会被执行，
     * 如果select()方法执行的过程中出现了异常，那么返回后通知是不会被执行。
     * 后置通知是不管原始方法有没有抛出异常都会被执行。这个案例大家下去可以自己练习验证下。
     *
     * @AfterReturning("ptx()")
     * 设置当前通知方法与切入点之间绑定关系，当前通知方法在原始切入点方法正常执行完毕后执行
     *
     * @AfterThrowing("ptx()")
     * 设置当前通知方法与切入点之间绑定关系，当前通知方法在原始切入点方法运行抛出异常后执行设置
     * 当前通知方法与切入点之间绑定关系，当前通知方法在原始切入点方法运行抛出异常后执行
     */

    @AfterReturning("ptx()")
    public void afters(){
        System.out.println("afterReturning advice ...");
    }

}